package org.xxpay.pay.channel.payeasepay;

import com.alibaba.fastjson.JSONObject;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.domain.api.AbstractRes;
import org.xxpay.core.common.domain.api.ApiBuilder;
import org.xxpay.core.common.domain.api.PayRes;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.util.AmountUtil;
import org.xxpay.core.common.util.MyBase64;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.MySeq;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;
import org.xxpay.pay.channel.payeasepay.demo.CFCA.MerchantX509Cert;
import org.xxpay.pay.channel.payeasepay.util.XmlUtils;
import org.xxpay.pay.mq.BaseNotify4MchPay;
import org.xxpay.pay.util.Util;

import javax.ws.rs.core.MultivaluedMap;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
* @author: zhuxiao
* @date: 18/12/13
* @description: 首信易支付接口
*/
@Service
public class PayeasepayPaymentService extends BasePayment {

    @Autowired
    public BaseNotify4MchPay baseNotify4MchPay;

    private static final MyLog _log = MyLog.getLog(PayeasepayPaymentService.class);

    @Override
    public String getChannelName() {
        return PayeasepayConfig.CHANNEL_NAME_PAYEASEPAY;
    }

    @Override
    public String getOrderId(PayOrder payOrder) {
        PayeasepayConfig payeasepayConfig = new PayeasepayConfig(getPayParam(payOrder));
        // 商户ID
        String v_mid = payeasepayConfig.getV_mid();
        SimpleDateFormat fm = new SimpleDateFormat("yyyyMMdd");
        return fm.format(new Date()) + "-" + v_mid + "-" + MySeq.getPayHmsSeq();
    }

    /**
     * 支付
     *
     * @param payOrder
     * @return
     */
    @Override
    public AbstractRes pay(PayOrder payOrder) {
        String channelId = payOrder.getChannelId();
        AbstractRes retObj;
        switch (channelId) {
            case PayeasepayConfig.PAY_CHANNEL_PAYEASEPAY_BANK_B2C:
                retObj = doGatewayReq(payOrder);
                break;
            default: return ApiBuilder.bizError("不支持的支付宝渠道[channelId=" + channelId + "]");
        }
        return retObj;
    }

    /**
     * 首信易网银支付
     *
     * @param payOrder
     * @return
     */
    public AbstractRes doGatewayReq(PayOrder payOrder) {
        PayeasepayConfig payeasepayConfig = new PayeasepayConfig(getPayParam(payOrder));
        PayRes retObj = ApiBuilder.buildSuccess(PayRes.class);
        try {
            String reqUrl = payeasepayConfig.getReqUrl();                                                               // 接口地址
            String url = reqUrl + "/prs/user_payment.checkit";
            if (reqUrl.endsWith("/")) {
                url = reqUrl + "prs/user_payment.checkit";
            }
            Map<String, String> queryParams = new HashMap<>();

            String payOrderId = payOrder.getPayOrderId();
            retObj.setPayOrderId(payOrderId);
            String v_mid = payeasepayConfig.getV_mid();                                                                 //商户编号
            String v_oid = payOrderId;                                                                                  //订单编号
            String v_moneytype = "0";                                                                                   //支付币种
            String v_ymd = new SimpleDateFormat("yyyyMMdd").format(new Date());                                         //订单产生日期
            String v_amount = AmountUtil.convertCent2Dollar(payOrder.getAmount() + "");                                 //订单总金额
            String v_rcvname = v_mid;                                                                                   //收货人姓名
            String v_rcvpost = v_mid;                                                                                   //收货人邮编
            String v_url = super.getReturnUrl(getChannelName(), null);                                                    //返回商户页面地址
            String v_rcvaddr = v_mid;                                                                                   //收货人地址
            String v_rcvtel = v_mid;                                                                                    //收货人电话
            String v_orderstatus = "1";                                                                                 //商户配货状态
            String v_ordername = v_mid;                                                                                 //订货人姓名

            String pfxFile = getCertFilePath(getChannelName(), payConfig.getCertRootPath(), payeasepayConfig.getPfxFile());                          //私钥证书
            String pfxPassword = payeasepayConfig.getPfxPassword();                                                     //证书
            String aliasPassword = payeasepayConfig.getAliasPassword();                                                 //别名密码
            String aliasName = payeasepayConfig.getAliasName();                                                         //别名
            String beforeSignSrc = v_moneytype + v_ymd + v_amount + v_rcvname + v_oid + v_mid + v_url;
            String sign;
            sign = MerchantX509Cert.sign(beforeSignSrc, pfxFile, aliasName, pfxPassword, aliasPassword);

            queryParams.put("v_mid", v_mid);
            queryParams.put("v_oid", v_oid);
            queryParams.put("v_moneytype", v_moneytype);
            queryParams.put("v_ymd", v_ymd);
            queryParams.put("v_amount", v_amount);
            queryParams.put("v_rcvname", v_rcvname);
            queryParams.put("v_rcvpost", v_rcvpost);
            queryParams.put("v_url", v_url);
            queryParams.put("v_rcvaddr", v_rcvaddr);
            queryParams.put("v_rcvtel", v_rcvtel);
            queryParams.put("v_orderstatus", v_orderstatus);
            queryParams.put("v_ordername", v_ordername);
            queryParams.put("v_md5info", sign);

            // 支付通道跳转表单
            StringBuffer payForm = new StringBuffer();
            payForm.append("<form id=\"test\" name=\"test\" action=\""+url+"\" method=\"post\">");
            for(String k : queryParams.keySet()) {
                payForm.append("<input type=\"hidden\" name=\""+k+"\" id=\""+k+"\" value=\""+queryParams.get(k)+"\">");
            }
            payForm.append("<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >");
            payForm.append("</form>");
            payForm.append("<script>document.forms[0].submit();</script>");

            // 构建xxpay服务端跳转表单
            String params = MyBase64.encode(payForm.toString().getBytes());
            String jumpForm = Util.buildJumpForm(super.getJumpUrl(null), params);

            int result = commonService.payOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);
            _log.info("[{}]更新订单状态为支付中:payOrderId={},result={}", getChannelName(), payOrder.getPayOrderId(), result);
            // 支付链接地址
            retObj.setJumpInfo(jumpForm);
            return retObj;

        } catch (Exception e) {
            _log.error(e, "");
        }
        return retObj;
    }

    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public QueryRetMsg query(PayOrder payOrder) {
        PayeasepayConfig payeasepayConfig = new PayeasepayConfig(getPayParam(payOrder));
        JSONObject retObj = new JSONObject();
        try {
            String reqUrl = payeasepayConfig.getReqUrl();                                                               // 接口地址
            String url = reqUrl + "/merchant/order/order_ack_oid_list.jsp";
            if (reqUrl.endsWith("/")) {
                url = reqUrl + "merchant/order/order_ack_oid_list.jsp";
            }
            System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
            Client cc = Client.create();
            WebResource rr = cc.resource(url);
            MultivaluedMap queryParams = new MultivaluedMapImpl();
            String payOrderId = payOrder.getPayOrderId();
            retObj.put("payOrderId",payOrderId);

            String v_mid = payeasepayConfig.getV_mid();                                                                 //商户编号
            String v_oid = payOrderId;                                                                                  //订单编号
            String pfxFile = getCertFilePath(getChannelName(), payConfig.getCertRootPath(), payeasepayConfig.getPfxFile());                          //私钥证书
            String pfxPassword = payeasepayConfig.getPfxPassword();                                                     //证书
            String aliasPassword = payeasepayConfig.getAliasPassword();                                                 //别名密码
            String aliasName = payeasepayConfig.getAliasName();                                                         //别名
            String publicKey = getCertFilePath(getChannelName(), payConfig.getCertRootPath(), payeasepayConfig.pubkeyName);                          //公钥证书
            String beforeSignSrc = v_mid + v_oid;
            String sign;
            sign = MerchantX509Cert.sign(beforeSignSrc, pfxFile, aliasName, pfxPassword, aliasPassword);

            queryParams.add("v_mid", v_mid);
            queryParams.add("v_oid", v_oid);
            queryParams.add("v_md5info", sign);
            String ret = rr.queryParams(queryParams).post(String.class);
            Map<String,String> resultMap = XmlUtils.xml2Map(ret);
            if (resultMap.get("status") != "0"){
                return QueryRetMsg.unknown(); //状态未知
            }
            //验签
            String signSrc = resultMap.get("oid") + resultMap.get("pstatus") + resultMap.get("amount") + resultMap.get("moneytype");
            String v_sign = resultMap.get("sign");
            Boolean result = MerchantX509Cert.verifySign(signSrc,v_sign,publicKey);
            if (result == false){
                return QueryRetMsg.unknown(); //状态未知
            }
            String v_pstatus = resultMap.get("pstatus");
            if ( "1".equals(v_pstatus) && "1".equals(resultMap.get("isvirement"))){ //支付成功

                return QueryRetMsg.confirmSuccess(resultMap.get("oid"));

            }else if ( "0".equals(v_pstatus) && "2".equals(v_pstatus) ){ //支付结果未确认
                return QueryRetMsg.waiting();
            }else if ( "3".equals(v_pstatus) && "4".equals(v_pstatus) && "6".equals(v_pstatus) && "7".equals(v_pstatus) && "8".equals(v_pstatus) ){ //支付失败
                return QueryRetMsg.confirmFail();
            }else if ( "5".equals(v_pstatus) ){ //退款已成功
                return QueryRetMsg.confirmFail();
            }else {
                return QueryRetMsg.unknown(); //未知状态
            }
        } catch (Exception e) {
            return QueryRetMsg.sysError();
        }
    }

}
